package com.qf.controller;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qf.dto.ApiResult;
import com.qf.entity.OrderEvaluate;
import com.qf.entity.request.OrderRequest;
import com.qf.entity.response.AlipayNotifyParam;
import com.qf.entity.response.OrderResponse;
import com.qf.enums.OrderEnum;
import com.qf.service.IOrderService;
import com.qf.utils.AlipayUtil;
import com.qf.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author chen
 * @since 2021-03-23
 */
@RestController
@RequestMapping("/order")
@Api(tags = "订单相关控制器")
public class OrderController {

    @Autowired
    private IOrderService orderService;


    @RequestMapping(value = "getOrder", method = RequestMethod.POST)
    @ApiOperation("生成订单")
    @CrossOrigin
    public ApiResult getOrder(@RequestBody List<OrderRequest> orderRequest) {
        Long orderId = orderService.getOrder(orderRequest);
        return R.ok(orderId);
    }

    @RequestMapping(value = "/orderDesc/{id}", method = RequestMethod.POST)
    @ApiOperation("订单详情")
    @CrossOrigin
    public ApiResult orderDesc(@PathVariable String id) {
        OrderResponse response = orderService.orderDesc(id);
        return R.ok(response);
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ApiOperation("订单列表")
    @CrossOrigin
    public ApiResult orderDesc() {
        List<OrderResponse> response = orderService.listOrder();
        return R.ok(response);
    }
    @RequestMapping(value = "/listAll", method = RequestMethod.POST)
    @ApiOperation("订单列表")
    @CrossOrigin
    public ApiResult listAll(@RequestBody OrderRequest orderRequest) {
        Page<OrderResponse> response = orderService.listOrderAll(orderRequest);
        return R.ok(response);
    }

    @RequestMapping(value = "/pay/{id}/{addressId}", method = RequestMethod.POST)
    @ApiOperation("付款")
    @CrossOrigin
    public ApiResult pay(@PathVariable String id,@PathVariable String addressId, HttpServletResponse response) throws AlipayApiException, IOException {
        String url = orderService.pay(id,addressId);
        return R.ok(url);
    }

    @RequestMapping(value = "/doGoods/{id}", method = RequestMethod.POST)
    @ApiOperation("收货")
    @CrossOrigin
    public ApiResult doGoods(@PathVariable String id) {
        orderService.changeOrder(OrderEnum.D,id,null);
        return R.ok();
    }


    @RequestMapping(value = "/evaluate/{id}", method = RequestMethod.POST)
    @ApiOperation("评价")
    @CrossOrigin
    public ApiResult evaluate(@RequestBody OrderEvaluate orderEvaluate,@PathVariable String id) {
        orderService.evaluate(id,orderEvaluate);
        return R.ok();
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ApiOperation("删除订单")
    @CrossOrigin
    public ApiResult delete(@PathVariable String id) {
        orderService.removeById(id);
        return R.ok();
    }


    /**
     * <pre>
     * 第一步:验证签名,签名通过后进行第二步
     * 第二步:按一下步骤进行验证
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     * </pre>
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/alipay_callback",method = RequestMethod.GET)
    @ResponseBody
    public ApiResult callback(HttpServletRequest request,HttpServletResponse response) {
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        try {
            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayUtil.alipay_public_key,
                    AlipayUtil.charset, AlipayUtil.sign_type);
            if (signVerified) {
                AlipayNotifyParam alipayNotifyParam = buildAlipayNotifyParam(params);
                //修改订单状态
                orderService.changeOrder(OrderEnum.C,alipayNotifyParam.getOutTradeNo(),null);
                response.sendRedirect("http://127.0.0.1:8848/item-shop/page/orderdesc.html?id="+alipayNotifyParam.getOutTradeNo());
            }
        } catch (AlipayApiException e) {
            return R.fail();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.fail();
    }

    @RequestMapping(value = "/alipay_notify",method = RequestMethod.POST)
    @ResponseBody
    public ApiResult notify(HttpServletRequest request,HttpServletResponse response) {
//        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
//        try {
//            // 调用SDK验证签名
//            boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayUtil.alipay_public_key,
//                    AlipayUtil.charset, AlipayUtil.sign_type);
//            if (signVerified) {
//                AlipayNotifyParam alipayNotifyParam = buildAlipayNotifyParam(params);
//                Map<String,String> map = new HashMap<>();
//                map.put("out_trade_no",alipayNotifyParam.getOutTradeNo());
//                map.put("trade_no",alipayNotifyParam.getTradeNo());
//                AlipayTradeQueryResponse search = AlipayUtil.search(map);
//                String out_trade_no = params.get("out_trade_no");
//                //修改订单状态
//                String addressId = URLEncoder.encode(params.get("passback_params"),"UTF-8");
//                orderService.changeOrder(OrderEnum.C,out_trade_no,addressId);
//                response.sendRedirect("http://127.0.0.1:8848/item-shop/page/orderdesc.html?id="+out_trade_no);
//            }
//        } catch (AlipayApiException e) {
//            return R.fail();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        return R.fail();
    }


    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }

    private AlipayNotifyParam buildAlipayNotifyParam(Map<String, String> params) {
        String json = JSON.toJSONString(params);
        return JSON.parseObject(json, AlipayNotifyParam.class);
    }

    private void check(Map<String, String> params) throws AlipayApiException {

        // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，

        // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），

        // 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
        // 第三步可根据实际情况省略

        // 4、验证app_id是否为该商户本身。

    }


}
